package com.weiun.common.core.controller;


import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.SecureUtil;
import com.weiun.common.base.bean.ParamBean;
import com.weiun.common.base.exception.BizMsgException;
import com.weiun.common.base.exception.OvertimeException;
import org.apache.commons.lang.StringUtils;

import javax.servlet.http.HttpServletRequest;

/**
 * The type Base controller.
 * 基础控制
 */
public class BaseController {

    protected final String HERDER_KEY_TIME = "time";
    protected final String HERDER_KEY_VERSION = "version";
    protected final String HERDER_KEY_DEVICES = "devices";
    protected final String HERDER_KEY_MODEL = "model";
    protected final String HERDER_KEY_SID = "sid";
    protected final String HERDER_KEY_SIGN = "sign";


    public ParamBean getParamBean(HttpServletRequest request) throws Exception {
        String time = request.getHeader(HERDER_KEY_TIME);
        String version = request.getHeader(HERDER_KEY_VERSION);
        String devices = request.getHeader(HERDER_KEY_DEVICES);
        String model = request.getHeader(HERDER_KEY_MODEL);
        String sid = request.getHeader(HERDER_KEY_SID);
        String sign = request.getHeader(HERDER_KEY_SIGN);
        if (StrUtil.hasEmpty(time, version, devices, model, sid, sign)) {
            throw new BizMsgException("Time version devices model sid sign cannot be empty");
        }
        ParamBean paramBean = new ParamBean();
        String realAddress = getRealAddress(request);
        paramBean.setTime(time);
        paramBean.setVersion(version);
        paramBean.setDevices(devices);
        paramBean.setModel(model);
        paramBean.setSid(sid);
        paramBean.setSign(sign);
        paramBean.setIp(realAddress);
        setAuthInfo(paramBean);
        return paramBean;
    }

    /**
     * Sets auth info.
     * 设置认证信息
     *
     * @param paramBean the param bean
     */
    public void setAuthInfo(ParamBean paramBean) {
        // 默认空实现，子类有必要需重写
    }

    public void checkParam(ParamBean paramBean) throws Exception {
        // 签名效验
        String time = paramBean.getTime();
        Long now = System.currentTimeMillis();
        long abs = Math.abs(now - Long.parseLong(time));
        if (abs > 1000 * 60 * 30) {
            throw new OvertimeException();
        } else {
            StringBuffer sb = new StringBuffer();
            sb.append(paramBean.getModel());
            sb.append("&");
            sb.append(paramBean.getDevices());
            sb.append("&");
            sb.append(paramBean.getTime());
            sb.append("&");
            sb.append(paramBean.getVersion());
            sb.append("&");
            sb.append(paramBean.getService());
            sb.append("&");
            sb.append(paramBean.getMethod());
            String md5 = SecureUtil.md5(sb.toString());
            if (!paramBean.getSign().equals(md5)) {
                throw new BizMsgException("Invalid request");
            }
        }
    }

    /**
     * Gets real address.
     * 获取真实的请求地址
     *
     * @param request the request
     * @return the real address
     */
    public static String getRealAddress(HttpServletRequest request) {
        String ip = request.getHeader("X-Forwarded-For");
        if (StringUtils.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("Proxy-Client-IP");
        }

        if (StringUtils.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("WL-Proxy-Client-IP");
        }

        if (StringUtils.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("HTTP_CLIENT_IP");
        }

        if (StringUtils.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("HTTP_X_FORWARDED_FOR");
        }

        if (StringUtils.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getRemoteAddr();
        }
        return ip;
    }
}
